home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / wtek0693.zip / OOPALLEY.ZIP / LIST.CPP < prev    next >
C/C++ Source or Header  |  1993-04-27  |  7KB  |  271 lines

  1. #include "list.h"
  2.  
  3. #define THIS    LinkedList
  4. #define BASE    SeqCltn
  5. DEFINE_CLASS(LinkedList,SeqCltn);
  6.  
  7. LinkedList::LinkedList()
  8. {
  9.     firstLink = lastLink = (Link*)nil;
  10.     count = 0;
  11. }
  12.  
  13. bool LinkedList::operator==(const LinkedList& ll) const
  14. {
  15.     if (count != ll.count) return NO;
  16.     else {
  17.         register Link* p = firstLink;
  18.         register Link* q = ll.firstLink;
  19.         while (p != (Link*)nil) {
  20.             if (!(p->isEqual(*q))) return NO;
  21.             p = p->nextLink();
  22.             q = q->nextLink();
  23.         }
  24.     }
  25.     return YES;
  26. }
  27.  
  28. Object* LinkedList::add(const Object& ob)
  29. {
  30.     assertArgClass(ob,class_Link,"add");
  31.     register Link* lnk = (Link*)&ob;
  32.     if (lnk->nextLink() != (Link*)nil) errDblLnk("add",*lnk);
  33.     if (count == 0) firstLink = lnk;
  34.     else lastLink->nextLink(lnk);
  35.     lastLink = lnk;
  36.     count++;
  37.     return (Object*)&ob;
  38. }
  39.  
  40. Collection& LinkedList::addContentsTo(Collection& cltn) const
  41. {
  42.     register Link* p = firstLink;
  43.     while (p != (Link*)nil) {
  44.         register Link* t = (Link*)p->copy();
  45.         t->nextLink((Link*)nil);
  46.         cltn.add(*t);
  47.         p = p->nextLink();
  48.     }
  49.     return cltn;
  50. }
  51.  
  52. Object* LinkedList::addFirst(const Object& ob)
  53. {
  54.     assertArgClass(ob,class_Link,"addFirst");
  55.     if (count == 0) return add(ob);
  56.     else {
  57.         register Link* lnk = (Link*)&ob;
  58.         if (lnk->nextLink() != (Link*)nil) errDblLnk("addFirst",*lnk);
  59.         lnk->nextLink(firstLink);
  60.         firstLink = lnk;
  61.         count++;
  62.         return (Object*)&ob;
  63.     }
  64. }
  65.  
  66. Object* LinkedList::addLast(const Object& ob) { return add(ob); }
  67.  
  68. Object*& LinkedList::operator[](int i) const
  69. {
  70.     if ((unsigned)i >= count) indexRangeErr();
  71.     if (i==0) return (Object*)firstLink;
  72.     else {
  73.         register Link* p = firstLink;
  74.         for (register int j=i-1; j>0; j--) p = p->nextLink();
  75.         return (Object*)p->next;
  76.     }
  77. }
  78.  
  79. Object*& LinkedList::at(int i)  const { return (*this)[i]; }
  80.  
  81. void LinkedList::atAllPut(const Object&) { shouldNotImplement("atAllPut"); }
  82.  
  83. void LinkedList::deepenShallowCopy()
  84. {
  85.     BASE::deepenShallowCopy();
  86.     register Link* p = firstLink;
  87.     firstLink = lastLink = (Link*)nil;
  88.     count = 0;
  89.     while (p != (Link*)nil) {
  90.         add(*(p->deepCopy()));
  91.         p = p->nextLink();
  92.     }
  93. }
  94.  
  95. #pragma warn -rvl   // Turn of Warning: Function should return a value
  96. Object* LinkedList::first()  const
  97. {
  98.     if (count==0) 
  99.     {
  100.         errEmpty("first");                          // aborts, return not executed
  101.         // return (Object*)NULL;                       // avoids Warning message
  102.     }else 
  103.         return firstLink;
  104. }
  105. #pragma warn .rvl
  106.  
  107. unsigned LinkedList::hash() const
  108. {
  109.     register unsigned h = count;
  110.     register Link* p = firstLink;
  111.     while (p != (Link*)nil) {
  112.         h^= p->hash();
  113.         p = p->nextLink();
  114.     }
  115.     return h;
  116. }
  117.  
  118. int LinkedList::indexOf(const Object& ob)  const
  119. {
  120.     register int i = 0;
  121.     register Link* p = firstLink;
  122.     while (p != (Link*)nil) {
  123.         if (p->isEqual(ob)) return i;
  124.         p = p->nextLink();
  125.         i++;
  126.     }
  127.     return -1;
  128. }
  129.  
  130. int LinkedList::indexOfSubCollection(const SeqCltn& /*cltn*/,
  131.                                      int /*start*/) const
  132. {   shouldNotImplement("indexOfSubCollection"); return 0;   }
  133.  
  134. bool LinkedList::isEmpty() const { return count==0; }
  135.  
  136. bool LinkedList::isEqual(const Object& a) const
  137. {
  138.     return a.isSpecies(class_LinkedList) && *this==*(LinkedList*)&a;
  139. }
  140.  
  141. const Class* LinkedList::species() const { return &class_LinkedList; }
  142.  
  143. #pragma warn -rvl   // Turn of Warning: Function should return a value
  144. Object* LinkedList::last() const
  145. {
  146.     if (count==0) 
  147.     {
  148.         errEmpty("last");                           // aborts, return not executed
  149.         // return (Object*)NULL;                       // avoids Warning message
  150.     } else 
  151.         return lastLink;
  152. }
  153. #pragma warn .rvl
  154.  
  155. Object* LinkedList::doNext(Iterator& pos) const
  156. {
  157.     if (pos.ptr == 0) {
  158.         if (firstLink == nil) return 0;
  159.         else {
  160.             pos.ptr = firstLink;
  161.             pos.index = 1;
  162.             return firstLink;
  163.         }
  164.     }
  165. else    if ((Link*)pos.ptr == lastLink) return 0;
  166. else        {
  167.         pos.ptr = ((Link*)pos.ptr)->nextLink();
  168.         pos.index++;
  169.         return (Object*)pos.ptr;
  170.     }
  171. }
  172.  
  173. unsigned LinkedList::occurrencesOf(const Object& ob) const
  174. {
  175.     register unsigned n=0;
  176.     register Link* p = firstLink;
  177.     while (p != (Link*)nil) {
  178.         if (p->isEqual(ob)) n++;
  179.         p = p->nextLink();
  180.     }
  181.     return n;
  182. }
  183.  
  184. void LinkedList::printOn(ostream& strm) const
  185. {
  186.     strm << className() << "[\n";
  187.     register unsigned i = 0;
  188.     register Link* p = firstLink;
  189.     while (p != (Link*)nil) {
  190.         if (i>0) strm << "\n";
  191.         p->printOn(strm);
  192.         p = p->nextLink();
  193.         i++;
  194.     }
  195.     strm << "]\n";
  196. }
  197.  
  198. Object* LinkedList::remove(const Object& ob)
  199. {
  200.     assertArgClass(ob,class_Link,"remove");
  201.     if (count==0) errEmpty("remove");
  202.     register Link* lnk = (Link*)&ob;
  203.     if (lnk == firstLink) {
  204.         firstLink = lnk->nextLink();
  205.         if (lnk == lastLink) lastLink = (Link*)nil;
  206.         goto wrapup;
  207.     }
  208.     else {
  209.         register Link* p = firstLink;
  210.         while (p != (Link*)nil) {
  211.             if (lnk == p->nextLink()) {
  212.                 p->nextLink(lnk->nextLink());
  213.                 if (lnk == lastLink) lastLink = p;
  214.                 goto wrapup;
  215.             }
  216.             p = p->nextLink();
  217.         }
  218.         errNotFound("remove",ob);
  219.     }
  220. wrapup:
  221.     lnk->nextLink((Link*)nil);
  222.     count--;
  223.     return (Object*)&ob;
  224. }
  225.  
  226. Object* LinkedList::removeFirst()   { return remove(*firstLink); }
  227.  
  228. Object* LinkedList::removeLast()    { return remove(*lastLink); }
  229.     
  230. void LinkedList::replaceFrom(int /*start*/, int /*stop*/, const SeqCltn& /*replacement*/, int /*startAt*/)
  231. {
  232.     shouldNotImplement("replaceFrom");
  233. }
  234.  
  235. void LinkedList::reSize(unsigned /*newSize*/) {}
  236.  
  237. unsigned LinkedList::size() const { return count; }
  238.     
  239. void LinkedList::errDblLnk(const char* fn, const Link& lnk) const
  240. {
  241.     DTerror("", "");
  242.     cerr << "Attempt to add " << lnk.className()
  243.          << " to two " << className() << "s: "
  244.          << this << "->"
  245.          << className() << "::" << fn
  246.          << "((" << lnk.className() << "*)"
  247.          << &lnk << ")"
  248.          << "\n";
  249. }
  250.  
  251. void LinkedList::errEmpty(const char* fn) const
  252. {
  253.     DTerror("", "");
  254.     cerr << "Collection empty: "
  255.          << this << "->"
  256.          << className() << "::" << fn << "()"
  257.          << "\n";
  258. }
  259.  
  260. void LinkedList::errNotFound(const char* fn, const Object& ob) const
  261. {
  262.     DTerror("", "");  // non fatal
  263.     cerr << "Object not found: "
  264.          << this << "->"
  265.          << className() << "::" << fn
  266.          << "((" << ob.className() << "*)"
  267.          << &ob << ")"
  268.          << "\n";
  269. }
  270.  
  271.